<template>
  <div class="train-container">
    <!-- 拓扑选择部分 -->
    <div class="topology-section">
      <h3>选择网络拓扑</h3>
      <el-select v-model="selectedTopology" placeholder="请选择网络拓扑" @change="handleTopologySelect">
        <el-option v-for="item in topologyOptions" :key="item.value" :label="item.label" :value="item.value" />
      </el-select>
      <div class="tip-text" v-if="!selectedTopology">请先选择网络拓扑</div>
    </div>

    <!-- 文件选择部分 -->
    <div class="file-select-section" v-if="selectedTopology">
      <h3>选择训练文件</h3>
      <div class="file-selectors">
        <!-- 路由矩阵文件选择 -->
        <div class="file-selector">
          <h4>路由矩阵文件</h4>
          <el-select v-model="selectedRouteFile" placeholder="请选择路由矩阵文件" @change="handleRouteFileSelect">
            <el-option v-for="file in uploadedFiles" :key="file.path" :label="file.filename" :value="file.path" />
          </el-select>
        </div>

        <!-- 训练数据文件选择 -->
        <div class="file-selector">
          <h4>训练数据文件</h4>
          <el-select v-model="selectedTrainFile" placeholder="请选择训练数据文件" @change="handleTrainFileSelect">
            <el-option v-for="file in uploadedFiles" :key="file.path" :label="file.filename" :value="file.path" />
          </el-select>
        </div>
      </div>
      <div class="tip-text" v-if="uploadedFiles.length === 0">
        没有找到可用的文件，请先在模型选择页面上传文件
      </div>
    </div>

    <!-- 训练部分 -->
    <div class="training-section" v-if="selectedTrainFile && selectedRouteFile && selectedTopology">
      <div class="training-params">
        <h3>训练参数设置</h3>
        <el-form :model="trainingParams" label-width="120px">
          <el-form-item label="学习率">
            <el-input-number v-model="trainingParams.learningRate" :min="0.0001" :max="0.1" :step="0.0001" />
          </el-form-item>
          <el-form-item label="训练轮数">
            <el-input-number v-model="trainingParams.epochs" :min="1" :max="1000" :step="1" />
          </el-form-item>
          <el-form-item label="批次大小">
            <el-input-number v-model="trainingParams.batchSize" :min="1" :max="128" :step="1" />
          </el-form-item>
        </el-form>
      </div>

      <div class="action-buttons">
        <el-button type="primary" @click="startTraining" :loading="isTraining">开始训练</el-button>
        <el-button @click="stopTraining" :disabled="!isTraining">停止训练</el-button>
      </div>

      <div class="training-progress" v-if="isTraining">
        <h3>训练进度</h3>
        <el-progress :percentage="trainingProgress" />
        <div class="training-logs">
          <pre>{{ trainingLogs }}</pre>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { ElMessage } from 'element-plus'

const selectedTopology = ref('')
const selectedRouteFile = ref('')
const selectedTrainFile = ref('')
const uploadedFiles = ref([])
const isTraining = ref(false)
const trainingProgress = ref(0)
const trainingLogs = ref('')
let ws = null

const topologyOptions = [
  { value: 'topology1', label: 'USA Network' },
  { value: 'topology2', label: 'Topology Graph 2' }
]

const trainingParams = ref({
  learningRate: 0.001,
  epochs: 100,
  batchSize: 32
})

// 获取已上传的文件列表
const fetchUploadedFiles = async () => {
  try {
    const response = await fetch('http://localhost:3456/api/files')
    const data = await response.json()
    if (data.success) {
      uploadedFiles.value = data.files.map(file => ({
        ...file,
        path: file.path
      }))
    }
  } catch (error) {
    ElMessage.error('获取文件列表失败')
  }
}

// 选择拓扑时的处理
const handleTopologySelect = (value) => {
  selectedRouteFile.value = ''
  selectedTrainFile.value = ''
  trainingProgress.value = 0
  trainingLogs.value = ''
  fetchUploadedFiles()
}

// 选择路由文件时的处理
const handleRouteFileSelect = (filePath) => {
  trainingProgress.value = 0
  trainingLogs.value = ''
}

// 选择训练文件时的处理
const handleTrainFileSelect = (filePath) => {
  trainingProgress.value = 0
  trainingLogs.value = ''
}

// 开始训练
const startTraining = async () => {
  try {
    isTraining.value = true
    trainingProgress.value = 0
    trainingLogs.value = ''

    // 连接WebSocket获取实时训练进度
    ws = new WebSocket('ws://localhost:3457')
    
    ws.onmessage = (event) => {
      const data = JSON.parse(event.data)
      if (data.type === 'progress') {
        trainingProgress.value = data.value
      } else if (data.type === 'log') {
        trainingLogs.value += data.message + '\n'
      }
    }

    // 发送训练请求
    const response = await fetch('http://localhost:3456/api/train', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({
        topology: selectedTopology.value,
        trainFilePath: selectedTrainFile.value,
        routeFilePath: selectedRouteFile.value,
        params: trainingParams.value
      })
    })

    const result = await response.json()
    if (!result.success) {
      throw new Error(result.message)
    }

  } catch (error) {
    ElMessage.error('启动训练失败：' + error.message)
    isTraining.value = false
  }
}

// 停止训练
const stopTraining = async () => {
  try {
    const response = await fetch('http://localhost:3456/api/train/stop', {
      method: 'POST'
    })
    const result = await response.json()
    if (result.success) {
      isTraining.value = false
      ws?.close()
      ElMessage.success('训练已停止')
    }
  } catch (error) {
    ElMessage.error('停止训练失败')
  }
}

onMounted(() => {
  fetchUploadedFiles()
})
</script>

<style lang="scss" scoped>
.train-container {
  padding: 20px;
  background-color: #ecf0f3;
  border-radius: 12px;
  box-shadow: 10px 10px 10px #d1d9e6, -10px -10px 10px #f9f9f9;
}

.topology-section,
.file-select-section,
.training-section {
  margin-bottom: 30px;
  padding: 20px;
  background-color: #ecf0f3;
  border-radius: 8px;
  box-shadow: inset 2px 2px 4px #d1d9e6, inset -2px -2px 4px #f9f9f9;

  h3 {
    margin-bottom: 15px;
    color: #2c3e50;
  }
}

.file-selectors {
  display: flex;
  gap: 20px;
  margin-bottom: 15px;

  .file-selector {
    flex: 1;

    h4 {
      margin-bottom: 10px;
      color: #2c3e50;
    }
  }
}

.training-params {
  margin-bottom: 20px;
}

.action-buttons {
  margin-bottom: 20px;
  
  .el-button {
    margin-right: 10px;
  }
}

.training-logs {
  margin-top: 20px;
  padding: 10px;
  background-color: #f5f7fa;
  border-radius: 4px;
  max-height: 300px;
  overflow-y: auto;

  pre {
    margin: 0;
    white-space: pre-wrap;
    word-wrap: break-word;
  }
}

.tip-text {
  margin-top: 10px;
  color: #909399;
  font-size: 14px;
}

:deep(.el-select) {
  width: 100%;
}

:deep(.el-input-number) {
  width: 180px;
}
</style> 